package com.qys.livesMall.file.server.upload.controller;

import com.qys.livesMall.common.constants.Constants;
import com.qys.livesMall.common.result.R;
import com.qys.livesMall.common.utils.file.FileUtils;
import com.qys.livesMall.file.server.upload.config.UploadConfig;
import com.qys.livesMall.file.server.upload.model.FileBasePath;
import com.qys.livesMall.file.server.upload.model.UrlInfo;
import com.qys.livesMall.file.server.upload.service.UploadFileService;
import com.qys.livesMall.file.server.upload.service.impl.local.proper.LocalStorageProperties;
import com.qys.livesMall.file.server.upload.service.impl.oss.proper.OssStorageProperties;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

/**
 * 文件处理相关接口
 */
@Slf4j
@RestController
@RequestMapping("/api/app/common")
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class FileController {

    private final UploadFileService uploadFileService;

    @Autowired
    private OssStorageProperties properties;

    /**
     * 单个上传
     *
     * @param file 文件流
     * @param type 类型
     * @return
     */
    @PostMapping("/upload/{type}")
    public R<UrlInfo> uploadFile(MultipartFile file, @PathVariable String type) {
        try {
            // 上传并返回新文件名称
            String fileName = uploadFileService.uploadFile(file, type);
            return R.ok(UrlInfo.builder().fileName(fileName)
                    .newFileName(FileUtils.getName(fileName))
                    .originalFilename(file.getOriginalFilename())
                    .build());
        } catch (Exception e) {
            log.error("上传失败：", e);
            return R.fail(e.getMessage());
        }
    }

    /**
     * 批量上传
     *
     * @param files 文件流
     * @param type  类型
     * @return
     */
    @PostMapping("/uploads/{type}")
    public R<List<UrlInfo>> uploadFiles(List<MultipartFile> files, @PathVariable String type) {
        try {
            List<UrlInfo> urlInfos = new ArrayList<>(files.size());

            for (MultipartFile file : files) {
                // 上传并返回新文件名称
                String fileName = uploadFileService.uploadFile(file, type);

                UrlInfo urlInfo = UrlInfo.builder().fileName(fileName)
                        .newFileName(FileUtils.getName(fileName))
                        .originalFilename(file.getOriginalFilename())
                        .build();
                urlInfos.add(urlInfo);
            }

            return R.ok(urlInfos);
        } catch (Exception e) {
            return R.fail(e.getMessage());
        }
    }

    /**
     * 通用下载请求
     *
     * @param fileName 文件名称
     * @param delete   是否删除
     */
    @GetMapping("/download")
    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response) {
        try {
            if (!FileUtils.checkAllowDownload(fileName)) {
                throw new Exception("文件名称(" + fileName + ")非法，不允许下载。");
            }
            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
            String filePath = LocalStorageProperties.localFilePath + "download" + fileName;

            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, realFileName);
            FileUtils.writeBytes(filePath, response.getOutputStream());
            if (delete) {
                FileUtils.deleteFile(filePath);
            }
        } catch (Exception e) {
            log.error("下载文件失败", e);
        }
    }

    /**
     * 获取文件信息
     *
     * @param fileName 文件名称
     * @param response
     * @param request
     */
    @GetMapping("/file")
    public void getFile(@RequestParam String fileName, HttpServletResponse response, HttpServletRequest request) {
        uploadFileService.getLocalFile(fileName, response, request);
    }

    /**
     * 获取文件域名
     */
    @GetMapping("/getBasePath")
    public R<String> getBasePath() {
        if (properties.isOssUp()){
            return R.ok(properties.getBaseUrl());
        }else {
            return R.ok(LocalStorageProperties.localFilePath );
        }
    }

    /**
     * 获取当前文件上下文环境信息
     *
     * @return
     */
    @GetMapping("/environment")
    public R<FileBasePath> environment() {
        FileBasePath fileBasePath = new FileBasePath();
        fileBasePath.setOss(UploadConfig.isOss ? Constants.YesNo.YES : Constants.YesNo.NO);
        fileBasePath.setOssBaseUrl(OssStorageProperties.ossUrl);
        return R.ok(fileBasePath);
    }
}
